{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have seen that [using Guassian process can achieve a reasonable visibility approximation](./fov_approx_adv.ipynb) for a single point.\n",
    "This is achieved by sampling several optical axis directions on the sphere, calculating the visibility at these samples and regressing the visiblity for any rotations. The key is that we need to use the same samples and covariance matrix ($K$) for all the landmarks to regress the visibility of the landmarks in the same way.\n",
    "\n",
    "In this notebook, we will check how the hyper parameters changse with different landmarks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-22T10:17:20.513861Z",
     "start_time": "2020-08-22T10:17:17.589899Z"
    }
   },
   "outputs": [],
   "source": [
    "%reset -f\n",
    "%matplotlib notebook\n",
    "%reload_ext autoreload\n",
    "%autoreload 2\n",
    "import os\n",
    "import numpy as np\n",
    "from tqdm import tqdm_notebook\n",
    "\n",
    "import add_path\n",
    "import sampler\n",
    "import visibility as vis\n",
    "import fov_approx_gp as fgp\n",
    "\n",
    "import plotly\n",
    "import plotly.graph_objs as go\n",
    "from plotly.offline import iplot\n",
    "plotly.offline.init_notebook_mode(connected=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is to generate the visibility configuration for the Gaussian process approximation, we used [GPy](https://sheffieldml.github.io/GPy/) for the hyperparameters optimization of GP."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-22T10:17:21.152677Z",
     "start_time": "2020-08-22T10:17:20.518740Z"
    }
   },
   "outputs": [],
   "source": [
    "# induced data points for the GP\n",
    "# 30 50 70 100 120 150\n",
    "n_induced_fs = 70\n",
    "# n random landmarks to test\n",
    "n_train_landmarks = 1000\n",
    "# FoV\n",
    "hfov_deg = 45\n",
    "hfov_rad = np.deg2rad(hfov_deg)\n",
    "#\n",
    "sigmoid_k = 15\n",
    "#\n",
    "fix_gaussian_noise = 1e-10\n",
    "#\n",
    "fast_sigmoid=False\n",
    "\n",
    "# save basedir\n",
    "param_dir = '/home/zichao/sources/FIF_ws/src/rpg_information_field/act_map/trace'\n",
    "assert os.path.exists(param_dir), \"change the param_dir to an exiting folder\"\n",
    "abs_save_dir = os.path.join(param_dir, fgp.FoVApproximatorGP.base_savedir_nm,\n",
    "                            fgp.FoVApproximatorGP.uniqueName(hfov_deg, n_induced_fs, \n",
    "                                                             n_train_landmarks, sigmoid_k,\n",
    "                                                             fast_sigmoid))\n",
    "if not os.path.exists(abs_save_dir):\n",
    "    os.makedirs(abs_save_dir)\n",
    "print(\"Going to save in {0}\".format(abs_save_dir))\n",
    "\n",
    "# generate necessary data\n",
    "sample_fs = sampler.sampleSphereUniformArea(n_induced_fs)\n",
    "rand_lms = sampler.randomPointsOnSphere(n_train_landmarks, 3)\n",
    "# rand_lms = np.random.uniform(-1, 1, [n_train_landmarks, 3])\n",
    "# rand_lms = np.array([3 * v / np.linalg.norm(v) for v in rand_lms])\n",
    "\n",
    "# plotting\n",
    "print(\"Let's visualize the sampled camera directions and the random landmarks for training.\")\n",
    "trace_fs = go.Scatter3d(x=sample_fs[:, 0],\n",
    "                        y=sample_fs[:, 1],\n",
    "                        z=sample_fs[:, 2],\n",
    "                        name='Induced Points',\n",
    "                        mode='markers',\n",
    "                        marker=dict(color='rgb(0, 80, 200)', size=5))\n",
    "trace_pw = go.Scatter3d(x=rand_lms[:, 0],\n",
    "                        y=rand_lms[:, 1],\n",
    "                        z=rand_lms[:, 2],\n",
    "                        name='Random Landmarks (training)',\n",
    "                        mode='markers',\n",
    "                        marker=dict(color='rgb(150, 150, 150)',\n",
    "                                    size=3))\n",
    "layout = go.Layout(showlegend=False)\n",
    "iplot({\"data\": [trace_fs, trace_pw]})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-22T10:22:33.597129Z",
     "start_time": "2020-08-22T10:17:21.157593Z"
    }
   },
   "outputs": [],
   "source": [
    "print(\"Start training: this might take a while, you can reduce the n_train_landmarks if needed.\")\n",
    "hparams = {'rbf_var':[], 'rbf_length':[], 'gauss_var':[]}\n",
    "for i in tqdm_notebook(range(n_train_landmarks)):\n",
    "    m = fgp.trainGPFoVApproximatorSingle(sample_fs, hfov_rad,\n",
    "                                         rand_lms[i],\n",
    "                                         opt_restart=3, sigmoid_k=sigmoid_k,\n",
    "                                         fix_gaussian_noise=fix_gaussian_noise,\n",
    "                                         use_fast_sigmoid=fast_sigmoid)\n",
    "    hparams['rbf_var'].append(\n",
    "        np.asscalar(m.rbf.variance.astype(float)))\n",
    "    hparams['rbf_length'].append(\n",
    "        np.asscalar(m.rbf.lengthscale))\n",
    "    hparams['gauss_var'].append(\n",
    "        np.asscalar(m.Gaussian_noise.variance))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-22T10:22:33.885578Z",
     "start_time": "2020-08-22T10:22:33.604083Z"
    }
   },
   "outputs": [],
   "source": [
    "medians = {}\n",
    "# plot the hyper parameters\n",
    "trace_rbf_var = go.Histogram(x=hparams['rbf_var'], name='rbf var')\n",
    "medians['rbf_var'] = np.median(hparams['rbf_var'])\n",
    "\n",
    "trace_rbf_length = go.Histogram(x=hparams['rbf_length'], name='rbf len')\n",
    "medians['rbf_length'] = np.median(hparams['rbf_length'])\n",
    "\n",
    "trace_gaussian_var = go.Histogram(x=hparams['gauss_var'], name='gaussian n')\n",
    "medians['gauss_var'] = np.median(hparams['gauss_var'])\n",
    "\n",
    "print(\"The medians are:\")\n",
    "display(medians)\n",
    "\n",
    "fig = plotly.tools.make_subplots(rows=3, cols=1)\n",
    "fig.append_trace(trace_rbf_var, 1, 1)\n",
    "fig.append_trace(trace_rbf_length, 2, 1)\n",
    "fig.append_trace(trace_gaussian_var, 3, 1)\n",
    "iplot(fig)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-22T10:22:33.943576Z",
     "start_time": "2020-08-22T10:22:33.889585Z"
    }
   },
   "outputs": [],
   "source": [
    "# save the model using the median of the hyperparameters\n",
    "approx_data = {'sampled_fs': sample_fs, 'sigmoid_k': sigmoid_k, 'hfov_deg': hfov_deg,\n",
    "              'rbf_var': medians['rbf_var'], 'rbf_lengthscale': medians['rbf_length'],\n",
    "               'white_var': medians['gauss_var']}\n",
    "gp_approx = fgp.FoVApproximatorGP()\n",
    "gp_approx.setApproximatorData(approx_data)\n",
    "gp_approx.save(abs_save_dir)\n",
    "\n",
    "print(\"Saved in {}\".format(abs_save_dir))\n",
    "print(\"You can use eval_gp_fov_approx.ipynb to validate the approximation\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that the hyper parameters are not very different. Next we will try to [learn one set of parameters from many random landmarks](./gp_fit_all_landmarks.ipynb)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.17"
  },
  "notify_time": "10",
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
